package com.gxa.mobile.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gxa.service.GoodsRpcVo;
import com.gxa.core.result.Result;
import com.gxa.mobile.pojo.vo.TCartVo;
import com.gxa.mobile.service.ShoppingCarService;
import com.gxa.mobile.utils.PublicData;
import com.gxa.service.GoodsRpcService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * <h3>coffee</h3>
 * <p></p>
 *
 * @author : 你的名字
 * @date : 2024-03-28 16:51
 **/
@Service
@Slf4j
public class NewShoppingCarServiceImpl implements ShoppingCarService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private Redisson redisson;

    //dubbo远程调用
    @Reference
    private GoodsRpcService goodsRpcService;
    @Override
    public List<GoodsRpcVo> selectAllCart(Integer userId) {
        return null;
    }

    @Override
    public boolean deleteUserCart(Integer userId) {
        return false;
    }

    @Override
    public boolean deleteCart(Integer userId, Integer goodsId) {
        return false;
    }

    @Override
    public boolean reduceCartItemQuantity(Integer userId, Integer goodsId, Integer quantity) {
        return false;
    }

    @Override
    public TCartVo addCarts(Integer userId, Integer goodsId, Integer number) {
        return null;
    }

    @Override
    public boolean updateCart(Integer userId, Integer goodsId, Integer number) {
        return false;
    }

    @Override
    public Result<List<GoodsRpcVo>> buyShoppingAllCart(Integer userId) {
        return null;
    }

    @Override
    public Result<GoodsRpcVo> buyShoppingCart(Integer userId, Integer goodsId) {
        return null;
    }

    /*******************************************************************************/

    //向购物车中添加商品
    @Override
    public boolean addItem(Integer userId, Integer goodsId, Integer number) {
        String cartHashKey = PublicData.SHOPPINGCART_REDISHASHKEY + userId;

        RLock lock = redisson.getLock("cartLock" + userId);
        try {
            // 加锁
            lock.lock();

            // 检查商品是否已经存在于购物车中
            HashOperations<String, Object, Object> hashOps = redisTemplate.opsForHash();
            Integer existingNumber = (Integer) hashOps.get(cartHashKey, goodsId.toString());

            GoodsRpcVo goodsRpcVo = goodsRpcService.findGoodsById(goodsId);

            if (goodsRpcVo == null) {
                // 商品不存在于RPC服务中，处理错误情况
                log.error("Goods with ID {} not found in RPC service for user {}", goodsId, userId);
                return false;
            }

            // 序列化GoodsRpcVo对象为JSON字符串
            ObjectMapper objectMapper = new ObjectMapper();
            String serializedGoodsRpcVo = objectMapper.writeValueAsString(goodsRpcVo);

            // 如果商品已经存在，则更新数量
            if (existingNumber != null) {
                int newNumber = existingNumber + number;
                hashOps.put(cartHashKey, goodsId.toString(), newNumber);
            } else {
                // 如果商品不存在，则添加到购物车中
                hashOps.put(cartHashKey, goodsId.toString(), number);
            }

            // 将序列化后的GoodsRpcVo存储在Redis的哈希中，使用特定的key来标识
            String goodsRpcVoKey = ":goods:" + goodsId;
            hashOps.put(cartHashKey, goodsRpcVoKey, serializedGoodsRpcVo);

            // 操作成功返回true
            return true;
        } catch (Exception e) {
            // 异常处理，记录日志等
            log.error("Error adding item to cart for user {}", userId, e);
            return false;
        } finally {
            // 释放锁
            lock.unlock();
        }
    }
    //查看购物车
    @Override
    public List<GoodsRpcVo> selectCart(String userId) {
        String cartHashKey = PublicData.SHOPPINGCART_REDISHASHKEY + userId;
        RLock lock = redisson.getLock("cartLock" + userId);
        List<GoodsRpcVo> cartList = new ArrayList<>();
        try {
            // 加锁
            lock.lock();

            // 获取Redis的Hash操作
            HashOperations<String, Object, Object> hashOps = redisTemplate.opsForHash();

            // 获取购物车中所有商品ID的集合
            Set<Object> goodsIds = hashOps.keys(cartHashKey);

            for (Object goodsIdObj : goodsIds) {
                Integer goodsId = (Integer) goodsIdObj;
                Integer number = (Integer) hashOps.get(cartHashKey, goodsId);

                // 从Redis中获取序列化后的GoodsRpcVo对象
                String serializedGoodsRpcVo = (String) hashOps.get(cartHashKey, ":goods:" + goodsId);
                if (serializedGoodsRpcVo != null) {
                    ObjectMapper objectMapper = new ObjectMapper();
                    try {
                        GoodsRpcVo goodsRpcVo = objectMapper.readValue(serializedGoodsRpcVo, GoodsRpcVo.class);
                        goodsRpcVo.setCount(number); // 设置商品数量
                        cartList.add(goodsRpcVo);
                    } catch (IOException e) {
                        log.error("Error deserializing goodsRpcVo for item {} in cart of user {}", goodsId, userId, e);
                    }
                } else {
                    log.warn("GoodsRpcVo for item {} not found in cart of user {}", goodsId, userId);
                }
            }
            // 返回购物车列表
            return cartList;
        } catch (Exception e) {
            // 异常处理，记录日志等
            log.error("Error selecting cart for user {}", userId, e);
            return new ArrayList<>(); // 返回一个空的购物车列表
        } finally {
            // 释放锁
            lock.unlock();
        }
    }




}
